package convert

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"strings"
)

// Convert 将指定码表文件进行转换
func Convert(mb string) error {
	// 检查格式一致性
	form, err := checkForm(mb)
	if err != nil {
		return err
	}

	// 开始处理
	err = parse(mb, form)
	if err != nil {
		return err
	}

	return nil
}

func parse(mb string, duo bool) error {
	f, err := os.Open(mb)
	if err != nil {
		return err
	}
	defer f.Close()

	var prefix string
	if duo {
		prefix = "jidian_"
	} else {
		prefix = "duo_"
	}

	fo, err := os.Create(prefix + mb)
	if err != nil {
		return err
	}
	defer fo.Close()

	rd := bufio.NewReader(f)
	wd := bufio.NewWriter(fo)

	if duo {
		if err := toJiDian(rd, wd); err != nil {
			return err
		}
	} else {
		if err := toDuo(rd, wd); err != nil {
			return err
		}
	}

	fmt.Printf("******处理完毕，输出文件：[%s]\n", prefix+mb)

	return nil
}

func toDuo(rd *bufio.Reader, wd *bufio.Writer) error {
	for {
		line, _, err := rd.ReadLine()
		if err != nil {
			if err == io.EOF {
				break
			}
			return err
		}

		if isSkip(line) {
			wd.WriteString(string(line) + "\n")
			continue
		}

		// 处理
		duoStr := toDuoLine(line)
		wd.WriteString(duoStr + "\n")
	}

	return nil
}

func toDuoLine(line []byte) string {
	jdStr := string(line)

	s := strings.Split(jdStr, " ")

	res := s[1] + "	" + s[0]
	return res
}

func toJiDian(rd *bufio.Reader, wd *bufio.Writer) error {
	for {
		line, _, err := rd.ReadLine()
		if err != nil {
			if err == io.EOF {
				break
			}
			return err
		}

		if isSkip(line) {
			wd.WriteString(string(line) + "\n")
			continue
		}

		// 处理
		jdStr := toJiDianLine(line)
		wd.WriteString(jdStr + "\n")
	}

	return nil
}

func toJiDianLine(line []byte) string {
	duoStr := string(line)

	s := strings.Split(duoStr, "	")

	res := s[1] + " " + s[0]
	return res
}

// checkConsistency 检查格式一致性
// 不允许文件内同时存在多多和极点两种格式
// @return bool：是否是多多格式
// 				- true：是多多
func checkForm(mb string) (bool, error) {
	f, err := os.Open(mb)
	if err != nil {
		return false, err
	}
	defer f.Close()

	rd := bufio.NewReader(f)

	// 按行遍历
	// 找到第一行非注释
	// 是否是多多格式
	var fstForm bool
	for {
		line, _, err := rd.ReadLine()
		if err != nil {
			if err == io.EOF {
				break
			}
			return false, err
		}

		if isSkip(line) {
			continue
		}

		form, err := isDuo(line)
		if err != nil {
			return false, err
		}

		fstForm = form
		break
	}

	// 继续按行遍历，若发现与第一行格式不符的，报错
	for {
		line, _, err := rd.ReadLine()
		if err != nil {
			if err == io.EOF {
				break
			}
			return false, err
		}

		lineForm, err := isDuo(line)
		if err != nil {
			return false, err
		}
		if fstForm != lineForm {
			return false, fmt.Errorf("检查到文件内格式不一致，请检查是否文件内所有行都为多多或极点格式！")
		}
	}

	return fstForm, nil
}

// isSkip 判断本行是否是可跳过的字符
func isSkip(line []byte) bool {
	if line[0] == '#' {
		return true
	} else if len(line) == 0 {
		return true
	}
	for ind := range line {
		if line[ind] != ' ' && line[ind] != '	' {
			return false
		}
	}
	return true
}

// isDuo 判断一行是否是多多格式的
// @param line: 读取的一行
//
// @return bool：是否是多多格式
//				- true：多多格式
//				- false：极点格式
// @return error：错误
func isDuo(line []byte) (bool, error) {
	str := string(line)

	if strings.Contains(str, "	") {
		// 可能是多多
		s := strings.Split(str, "	")
		if len(s) != 2 {
			fmt.Println("%v", str)
			return false, fmt.Errorf("行内格式不正确！")
		}
		return true, nil
	} else if strings.Contains(str, " ") {
		// 可能是极点
		s := strings.Split(str, " ")
		if len(s) != 2 {
			fmt.Println("%v", str)
			return false, fmt.Errorf("行内格式不正确！")
		}
		return false, nil
	}

	return false, fmt.Errorf("行内格式不正确！")
}
